home *** CD-ROM | disk | FTP | other *** search
- #include<dos/dos.h>
- #include<dos/exall.h>
- #include<exec/libraries.h>
- #include<exec/memory.h>
- #include<graphics/text.h>
- #include<intuition/intuition.h>
- #include<intuition/screens.h>
- #include<libraries/gadtools.h>
- #include<utility/tagitem.h>
-
- #include<string.h>
- #include<stdio.h>
- #include<stdlib.h>
-
- #include<clib/alib_protos.h>
- #include<clib/dos_protos.h>
- #include<clib/exec_protos.h>
- #include<clib/gadtools_protos.h>
- #include<clib/intuition_protos.h>
-
- /* The library base global variables */
- struct Library* DosBase;
- struct Library* GadToolsBase;
- struct Library* IntuitionBase;
-
- /* Need to give prototypes for our functions */
- void handleIDCMP(struct Window*);
- void setupWindow(void);
- void createWindow(struct Gadget*);
-
- void addNode(char*);
- void freeNode(struct Node*);
- void freeList(void);
- int fillList(char*);
- void sortList(void);
-
- #define MYFONTSIZE (8)
-
- /* Some constants for the size of the window */
- #define MYWIN_WIDTH (200)
- #define MYWIN_HEIGHT (200)
-
- /* Some constants for the position and size of our gadget */
- #define MYGAD_LEFT (10)
- #define MYGAD_TOP (10+MYFONTSIZE)
- #define MYGAD_WIDTH (MYWIN_WIDTH-MYGAD_LEFT*2)
- #define MYGAD_HEIGHT (MYWIN_HEIGHT-MYGAD_TOP*2+MYFONTSIZE)
- #define MYGAD_TEXT ("Files")
- #define MYGAD_ID (0)
-
- /* Initialised structure declaration: describes standard Topaz font */
- static struct TextAttr topazFont = { "topaz.font", MYFONTSIZE, 0, 0, };
-
- static struct List mylist;
- static int mycount = 0;
-
- void addNode(char* name)
- {
- if(name)
- {
- struct Node* node = AllocVec(sizeof(struct Node), MEMF_PUBLIC | MEMF_CLEAR);
- if(node)
- {
- if(node->ln_Name = AllocVec(strlen(name)+1, MEMF_PUBLIC))
- strcpy(node->ln_Name, name);
- AddTail(&mylist, node);
- mycount++;
- }
- }
- }
-
- void freeNode(struct Node* node)
- {
- FreeVec(node->ln_Name);
- FreeVec(node);
- }
-
- void freeList()
- {
- struct Node* work;
- struct Node* next = mylist.lh_Head;
- while(next->ln_Succ)
- {
- work = next;
- next = next->ln_Succ;
- freeNode(work);
- }
- mycount = 0;
- }
-
- #define EABUFF_NUM (30)
- #define EABUFF_SIZE (EABUFF_NUM*sizeof(struct ExAllData))
-
- /* Our buffer for ExAll() */
- static struct ExAllData EABuff[EABUFF_NUM];
-
- int fillList(char* dir)
- {
- int success = FALSE;
- /* Get a lock on the directory */
- BPTR lock = Lock(dir, ACCESS_READ);
- if(lock)
- {
- /* Allocate ExAll control object */
- struct ExAllControl* eac = AllocDosObject(DOS_EXALLCONTROL,NULL);
- if(eac)
- {
- int going = TRUE;
- /* Must initialise LastKey to zero before calling ExAll() */
- eac->eac_LastKey = 0;
- /* If we got this far we're OK */
- success = TRUE;
- while(going)
- {
- /* Fill the buffer with directory entries */
- going = ExAll(lock, EABuff, EABUFF_SIZE, ED_NAME, eac);
- /* It's only an error if ExAll() returns FALSE and IoErr() signals */
- /* something other than running out of directory entries */
- if(!going)
- success = (IoErr() == ERROR_NO_MORE_ENTRIES);
- if(success)
- {
- if(eac->eac_Entries != 0)
- {
- /* Run through a buffer load of entries */
- struct ExAllData* ead = EABuff;
- while(ead)
- {
- addNode(ead->ed_Name);
- ead = ead->ed_Next;
- }
- }
- }
- }
- /* Print an error report if necessary */
- if(!success)
- PrintFault(IoErr(), "Error");
- FreeDosObject(DOS_EXALLCONTROL,eac);
- }
- else
- printf("Error: could not create ExAll control object\n");
- UnLock(lock);
- }
- else
- printf("Error: could not lock directory \"%s\"\n", dir);
- return success;
- }
-
- int compareNode(const void* a, const void* b)
- {
- struct Node** na = (struct Node**)a;
- struct Node** nb = (struct Node**)b;
- /* Use "strcmp()" if "stricmp()" doesn't work on your compiler */
- return stricmp((*na)->ln_Name, (*nb)->ln_Name);
- }
-
- void sortList()
- {
- if(mycount > 1)
- {
- struct Node** sortarray = malloc(mycount*sizeof(struct Node*));
- if(sortarray)
- {
- /* Copy pointers to the nodes into the array, in order */
- int i = 0;
- struct Node* next = mylist.lh_Head;
- while(next->ln_Succ)
- {
- sortarray[i++] = next;
- next = next->ln_Succ;
- }
- /* Sort the array of pointers */
- qsort(sortarray, mycount, sizeof(struct Node*), &compareNode);
- /* Clear the list, then refill it */
- NewList(&mylist);
- for(i=0; i<mycount; i++)
- AddTail(&mylist, sortarray[i]);
- free(sortarray);
- }
- }
- }
-
- /* The start of the program */
- void main()
- {
- /* Open libraries... */
- if(IntuitionBase = OpenLibrary("intuition.library",37))
- {
- if(GadToolsBase = OpenLibrary("gadtools.library",37))
- {
- if(DosBase = OpenLibrary("dos.library",37))
- {
- /* Now do the real work */
- NewList(&mylist);
- if(fillList("sys:"))
- {
- sortList();
- setupWindow();
- }
- freeList();
- CloseLibrary(DosBase);
- }
- else
- printf("Error: could not open dos.library\n");
- CloseLibrary(GadToolsBase);
- }
- else
- printf("Error: could not open gadtools.library\n");
- CloseLibrary(IntuitionBase);
- }
- else
- printf("Error: could not open intuition.library\n");
- }
-
- /* Setup the window -- do the GadTools stuff */
- void setupWindow()
- {
- struct Screen* scr;
- /* We'll copy the visual information for the default public screen */
- /* (usually, this is the Workbench screen) */
- if(scr = LockPubScreen(NULL))
- {
- APTR vinfo;
- /* Get the visual info so GadTools can render the gadgets nicely */
- if(vinfo = GetVisualInfo(scr, TAG_DONE))
- {
- struct Gadget* glist = NULL;
- struct Gadget* listgad;
- if(listgad = CreateContext(&glist))
- {
- struct NewGadget newgad;
- /* The offsets of our window borders */
- int offleft = scr->WBorLeft;
- int offtop = scr->WBorTop + (scr->Font->ta_YSize + 1);
- /* Setup our first gadget */
- newgad.ng_TextAttr = &topazFont;
- newgad.ng_VisualInfo = vinfo;
- newgad.ng_LeftEdge = MYGAD_LEFT + offleft;
- newgad.ng_TopEdge = MYGAD_TOP + offtop;
- newgad.ng_Width = MYGAD_WIDTH;
- newgad.ng_Height = MYGAD_HEIGHT;
- newgad.ng_GadgetText = MYGAD_TEXT;
- newgad.ng_GadgetID = MYGAD_ID;
- newgad.ng_Flags = 0;
- /* Now create it and add it to our list */
- if(listgad = CreateGadget(LISTVIEW_KIND, listgad, &newgad,
- GTLV_Labels, &mylist,
- TAG_DONE))
- createWindow(glist);
- else
- printf("Error: could not create gadget(s)\n");
- /* Free the gadget */
- FreeGadgets(glist);
- }
- else
- printf("Error: could not create GadTools context\n");
- FreeVisualInfo(vinfo);
- }
- else
- printf("Error: could not get visual info\n");
- UnlockPubScreen(NULL, scr);
- }
- else
- printf("Error: could not lock public screen\n");
- }
-
- /* Actually open the window, in the normal way */
- void createWindow(struct Gadget* glist)
- {
- struct Window* win;
- /* Open our window */
- if(win = OpenWindowTags(NULL,
- WA_InnerWidth, MYWIN_WIDTH,
- WA_InnerHeight, MYWIN_HEIGHT,
- WA_Title, "Directory List",
- WA_Flags, WFLG_CLOSEGADGET | WFLG_DRAGBAR,
- WA_IDCMP, IDCMP_CLOSEWINDOW | IDCMP_REFRESHWINDOW | LISTVIEWIDCMP,
- WA_Gadgets, glist,
- TAG_DONE, 0))
- {
- /* Let GadTools refresh its bits of the window */
- GT_RefreshWindow(win, NULL);
- /* Now handle messages */
- handleIDCMP(win);
- CloseWindow(win);
- }
- else
- printf("Error: could not open window\n");
- }
-
- /* Our message handling code */
- void handleIDCMP(struct Window* win)
- {
- int going = TRUE;
- while(going)
- {
- struct IntuiMessage* intuimsg;
- /* Wait for messages to arrive */
- WaitPort(win->UserPort);
- /* Messages have arrived: loop through all of them */
- while(intuimsg = GT_GetIMsg(win->UserPort))
- {
- /* Act on this message... */
- switch(intuimsg->Class)
- {
- case IDCMP_CLOSEWINDOW:
- going = FALSE;
- break;
- case IDCMP_REFRESHWINDOW:
- /* You *MUST* remember to ask for and handle these refresh messages */
- GT_BeginRefresh(win);
- GT_EndRefresh(win, TRUE);
- break;
- }
- /* Reply when finished with message */
- GT_ReplyIMsg(intuimsg);
- }
- }
- }
-
-